Documentation for Users  2.1.2
Perception Toolbox for Virtual Reality (PTVR) Manual
reticle_in_forest_with_spheres.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 """
3 ...\PTVR_Researchers\Python_Scripts\Demos\Pointing\
4  reticle_in_forest_with_spheres.py
5 
6 Goal of this demo:
7  Show how to create a Monocular (or binocular) STANDARD PTVR reticle.
8  Note that there is no pointing interaction between the reticle and the
9  spheres or objects (i.e. no callback is called when an object is
10  pointed at).
11 
12  The reticle is head-contingent in this demo
13 
14  The scene is a forest* with trees at different distances to observe
15  the reticle's behaviour when its pointing cone encounters objects or
16  nothing.
17 
18  * This forest is a PTVR object modified from the following free asset:
19  https://assetstore.unity.com/packages/3d/environments/landscapes/low-poly-simple-nature-pack-162153
20 
21  By default, a PTVR reticle is always rendered through any object
22  with its position calculated to be close to the object's center (See PTVR
23  Documentation -> User Manual -> Pointing at an object).
24  Thus, the similarity in position of the object and the reticle render
25  their binocular disparity similar thus avoiding double vision.
26  This default behaviour occurs when 'is_distance_constant' is set to
27  False (in ImageToContingentCursor() )
28  Another aspect of this default behaviour emerges when the reticle's pointing
29  cone is empty, i.e. when no object lies within the pointing cone. In
30  this case, the reticle is set to a distance that you can choose. This
31  distance is set to 500 m by default ('distance_if_empty_cursor_cone'=500).
32 
33 What you can play around with:
34  You can set a constant distance for the reticle (thus changing its
35  default behaviour).
36  For instance, if you want to have the reticle at 2 meters from the head,
37  gaze, eye, or hand, you have to modify the two following parameters of
38  ImageToContingentCursor :
39  is_distance_constant = True
40  constant_distance = 2
41  If you do as defined above, then the reticle will not be visible
42  when it is behind the red sphere (the spheres are displayed at different
43  distances from the CS's origin).
44 
45 Note : The reticle belongs to the PTVR category called "flat cursors"
46  (reminder: a scotoma also belongs to the "flat cursors" category).
47 
48 """
49 
50 from PTVR.Visual import The3DWorld
51 from PTVR.Stimuli.Scenes import VisualScene
52 from PTVR.Stimuli.Objects import Sphere, Forest, Sprite
53 import PTVR.Stimuli.Color as color
54 import numpy as np
55 from PTVR.Pointing.PointingCursor import *
57 
58 from PTVR.SystemUtils import LaunchThe3DWorld
59 
60 # =============================================================================
61 # PARAMETERS #
62 # =============================================================================
63 
64 my_contingency = ImageContingency.HEADSET
65 
66 my_eye_w_reticle = "both" # "right" or "left" or "both"
67 
68 
69 
70 sphere_1_color = color.RGBColor(1,0,0)
71 sphere_1_pos = np.array([-1,0,1])
72 sphere_2_color = color.RGBColor(0,1,0)
73 sphere_2_pos = np.array([0,0,3])
74 sphere_3_color = color.RGBColor(0,0,1)
75 sphere_3_pos = np.array([1,0,5])
76 # =============================================================================
77 # END PARAMETERS #
78 # =============================================================================
79 
80 
81 def create_reticle (scene_name):
82  # internally create a PNG file to create an image
83  reticle_2D_image = RG.ReticleImageFromDrawing (
84  reticle_inner_diameter_as_ratio = 0.3,
85  reticle_line_width_as_ratio=0.1 )
86  #reticle_2D_image.Show() # uncomment this line to show the image of the
87  # reticle in a new window of your PC
88 
89  my_reticle = ImageToContingentCursor (
90  contingency_type = my_contingency,
91  image = reticle_2D_image,
92  eye_with_contingent_cursor = my_eye_w_reticle,
93  is_distance_constant = False, # False by default
94  constant_distance = 2 )
95  scene_name.place_contingent_cursor (my_reticle)
96 # END of create_reticle ()
97 
98 def create_spheres (scene_name):
99  sphere_1 = Sphere ( color = sphere_1_color,
100  position_in_current_CS = sphere_1_pos)
101  sphere_2 = Sphere ( color = sphere_2_color,
102  position_in_current_CS = sphere_2_pos)
103  sphere_3 = Sphere ( color = sphere_3_color,
104  position_in_current_CS = sphere_3_pos)
105  scene_name.place (sphere_1, my_world)
106  scene_name.place (sphere_2, my_world)
107  scene_name.place (sphere_3, my_world)
108 # END of create_spheres ()
109 
110 
111 my_world = The3DWorld ()
112 def main():
113  # the simplest scene
114  my_scene = VisualScene (skybox= "Sunset", side_view_on_pc = False)
115  # Night, BrightMorning, Cloudy, Afternoon, or Sunset
116 
117  create_reticle (my_scene)
118  create_spheres (my_scene)
119 
120  my_forest = Forest ()
121  my_scene.place (my_forest, my_world)
122 
123  my_sprite = Sprite (image_file ="cat.png",
124  collider = True,
125  position_in_current_CS=np.array([3, 3, 0.0]) ,
126  rotation_in_current_CS=np.array([0.0, 90, 0.0]))
127  my_scene.place (my_sprite, my_world)
128 
129  my_world.add_scene (my_scene)
130  my_world.write ()
131 
132 if __name__ == "__main__":
133  main()
134  LaunchThe3DWorld() # Launch the Experiment with PTVR.
def LaunchThe3DWorld(jsonFileCategory="Externals")
Definition: SystemUtils.py:182